package cn.lg.soar.common.util.hardware;

import cn.lg.soar.common.util.data.RandomUtil;
import com.sun.management.OperatingSystemMXBean;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.RuntimeMXBean;
import java.util.List;

/**
 * 操作系统工具
 * @author luguoxiang
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class SystemUtils {

    private final static RuntimeMXBean BEAN = ManagementFactory.getRuntimeMXBean();
    private static String PROCESSOR_ID;

    public final static long TOTAL;
    public final static long MAX;

    static {
        Runtime rt = Runtime.getRuntime();
        TOTAL = rt.totalMemory();
        MAX = rt.totalMemory();
    }

    /**
     * 获取虚拟机启动时间
     * @return
     */
    public static long startTime(){
        return SystemUtils.BEAN.getStartTime();
    }

    /**
     * 获取系统运行时长
     * @return
     */
    public static long duration(){
        return System.currentTimeMillis() - SystemUtils.BEAN.getStartTime();
    }

    /**
     * 获取jvm信息
     * @return
     */
    public static JvmInfo getJvmInfo(){
        List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
        Runtime rt = Runtime.getRuntime();
        long free = rt.freeMemory();
        long total = rt.totalMemory();
        JvmInfo memory = new JvmInfo();
        memory.setMax(rt.maxMemory());
        memory.setTotal(total);
        memory.setFree(free);
        memory.setUsed(total - free);
        for(MemoryPoolMXBean pool : pools) {
            switch (pool.getName()) {
                case "Code Cache": memory.setCode(pool.getUsage()); break;
                case "Metaspace": memory.setMetaspace(pool.getUsage()); break;
                case "Compressed Class Space": memory.setCompressed(pool.getUsage()); break;
                case "PS Eden Space": memory.setEden(pool.getUsage()); break;
                case "PS Survivor Space": memory.setSurvivor(pool.getUsage()); break;
                case "PS Old Gen": memory.setOld(pool.getUsage()); break;
                default:break;
            }
        }
        return memory;
    }

    /**
     * 获取系统信息
     * @return
     */
    public static SystemInfo getSystemInfo() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        long free = osmxb.getFreePhysicalMemorySize();
        long total = osmxb.getTotalPhysicalMemorySize();
        SystemInfo systemInfo = new SystemInfo();
        systemInfo.setName(System.getProperty("os.name"));
        systemInfo.setTotal(total);
        systemInfo.setFree(free);
        systemInfo.setUsed(total - free);
        return systemInfo;
    }

    /**
     * 获取硬盘信息
     * @return
     */
    public static DiskInfo[] getDiskInfo() {
        File[] roots= File.listRoots();
        DiskInfo[] infos = new DiskInfo[ roots.length ];
        for (int i = 0; i < roots.length; i++) {
            File file = roots[ i ];
            long free = file.getFreeSpace();
            long total = file.getTotalSpace();
            DiskInfo info = new DiskInfo();
            info.setName(file.getPath());
            info.setTotal(total);
            info.setFree(free);
            info.setUsed(total - free);
            infos[i] = info;
        }
        return infos;
    }

    /**
     * 获取主机名
     * @return
     */
    public static String getProcessorId() {
        if (PROCESSOR_ID == null) {
            synchronized (SystemUtils.class) {
                if (PROCESSOR_ID == null) {
                    PROCESSOR_ID = RandomUtil.uuid();
                }
            }
        }
        return PROCESSOR_ID;
    }

    /**
     * 获取系统名称
     * @return
     */
    public static String getOsName() {
        return System.getProperty("os.name");
    }

    public static boolean isWindows() {
        String osName = getOsName();
        return osName != null && osName.startsWith("Windows");
    }

    public static boolean isMacOs() {
        String osName = getOsName();
        return osName != null && osName.startsWith("Mac");
    }

    public static boolean isLinux() {
        String osName = getOsName();
        return (osName != null && osName.startsWith("Linux"));
    }

}
